package com.tryee.wx.config.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.json.XML;
import com.tryee.common.utils.StringUtils;
import com.tryee.wx.config.constant.WeiXin;
import com.tryee.wx.pojo.WxTemplateMsg;
import javafx.beans.binding.StringBinding;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.tryee.wx.config.constant.WeiXin.CUSTOMURL;

/**
 * 微信配置类
 */
@Component("WxUtils")
@Slf4j
public class WxUtils {

    private final String REDISKEY = "weixin:";

    @Value("${wx.appid}")
    private String appid;

    @Value("${wx.appsecret}")
    private String appsecret;

    @Value("${wx.chatId}")
    private String chatId;

    @Autowired
    private RedisUtils redisUtils;

    private Logger logger = LoggerFactory.getLogger(WxUtils.class);

    /**
     * 设置token
     */
    public void setToken() {
        logger.info("============开始获取token=========");

        String accessToken = "";

        if (StringUtils.isEmpty(redisUtils.getToken())) {
            logger.info("============远程获取获取token=========");
            Map<String, Object> map = new HashMap<>();
            map.put("grant_type", "client_credential");
            map.put("appid", appid);
            map.put("secret", appsecret);
            String accessTokenStr = HttpUtil.get(WeiXin.ACCESSTOKEN, map);
            //从json字符串中解析token
            JSONObject tokenObj = JSONUtil.parseObj(accessTokenStr);
            accessToken=tokenObj.getStr("access_token");
            redisUtils.setToken(accessToken);
        }else{
            logger.info("============从redis中获取token=========");
            accessToken= redisUtils.getToken();
        }

        logger.info("获取成功token:" + accessToken);
    }

    /**
     * 获取token
     * @return
     */
    public  String getToken(){
        String token= redisUtils.getToken();
        if (StringUtils.isEmpty(token)) {
            this.setToken();
            return redisUtils.getToken();
        }
        return token;
    }

    /**
     * 获取模板列表
     */
    public  List<WxTemplateMsg> getTemplates(){
        Map<String, Object> map = new HashMap<>();
        map.put("access_token",this.getToken());
        String template = HttpUtil.get(WeiXin.TEMPLATEURL, map);

        JSONArray templates = JSONUtil.parseObj(template).getJSONArray("template_list");

        List<WxTemplateMsg> list = new ArrayList<>();
        for(int i=0;i<templates.size();i++) {
            JSONObject obj = templates.getJSONObject(i);



            String templateId=obj.getStr("template_id");
            String title=obj.getStr("title");
            String primary_industry=obj.getStr("primary_industry");
            String deputy_industry=obj.getStr("deputy_industry");
            String content=obj.getStr("content");
            String example=obj.getStr("example");

            WxTemplateMsg wxTemplateMsg = new WxTemplateMsg(
                    templateId,
                    title,
                    primary_industry,
                    deputy_industry,
                    content,example);

            list.add(wxTemplateMsg);
        }

        return list;

    }

    /**
     * 发送模板消息
     * @param postStr 用户openid
     * @return
     */
    public String sendTemplateMsg(String postStr){
        String result = HttpUtil.post(WeiXin.SENDTEMPLATEURL + "?access_token=" + getToken(), postStr);
        String errcode = "";
        if (JSONUtil.isJson(result)) {
            JSONObject jsonObject = JSONUtil.parseObj(result);
            errcode = jsonObject.getStr("errcode");
        }

        return errcode;
    }

    /**
     * 回复消息
     */
    public int replyMsg(String openid,String content){
        Map<String, Object> map = new HashMap<>();
        map.put("touser", openid);
        map.put("msgtype", "text");

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("content", content);
        map.put("text", jsonObject);
        String result = HttpUtil.post(CUSTOMURL + "?access_token=" + getToken(),JSONUtil.parseFromMap(map).toString() );

        JSONObject resultObj = JSONUtil.parseObj(result);
        if (resultObj != null && resultObj.getInt("errcode")==0) {
            return 0;
        }

        return -1;
    }


    /**
     * 根据code获得AccessToken和openid
     * @param code code
     * @return
     */
    public String getOpenid(String code){

        JSONObject resultObj = new JSONObject();
        //首先判断是否存在access_token 这个token是网页版的
        String website_access_token = redisUtils.getString("website_access_token");
        String website_refresh_token = redisUtils.getString("website_refresh_token");
        if (StringUtils.isNotBlank(website_refresh_token)) {
            resultObj = getOpenidByRefreshToken(website_refresh_token);
        }else{
            Map<String, Object> map = new HashMap<>();
            map.put("appid", appid);
            map.put("secret", appsecret);
            map.put("code", code);
            map.put("grant_type", "authorization_code");

            String returnUrl = HttpUtil.get(WeiXin.OPENID_URL, map);
            resultObj = JSONUtil.parseObj(returnUrl);

            setRefreshAccessToken(resultObj);
        }

        String openid=resultObj.getStr("openid");
        if (StringUtils.isBlank(openid)) {
            openid="";
        }

        return openid;
    }

    /**
     * 从缓存中获取access_toke 然后获得openid
     * @param refresh_token
     * @return
     */
    public JSONObject getOpenidByRefreshToken(String refresh_token){
        Map<String, Object> map = new HashMap<>();
        map.put("appid", appid);
        map.put("grant_type", "refresh_token");
        map.put("refresh_token", refresh_token);
        String returnUrl = HttpUtil.get(WeiXin.REFRESH_TOKEN_URL, map);
        JSONObject result = JSONUtil.parseObj(returnUrl);
        setRefreshAccessToken(result);
        return result;
    }

    public void setRefreshAccessToken(JSONObject jsonObject){
        String refresh_token = jsonObject.getStr("refresh_token");
        if (StringUtils.isNotBlank(refresh_token)) {
            redisUtils.setString("website_refresh_token",refresh_token, TimeUnit.DAYS,30);
        }
    }
}
